home *** CD-ROM | disk | FTP | other *** search
/ Mac Magazin/MacEasy 24 / Mac Magazin and MacEasy Magazine CD - Issue 24.iso / Grafik & Text / Microsoft Installer Patch / patches.c < prev    next >
Text File  |  1996-07-13  |  4KB  |  186 lines

  1. // patches.c
  2.  
  3. #include <Traps.h>
  4. #include <A4Stuff.h>
  5.  
  6. #include "patches.h"
  7.  
  8. // defines
  9. #define CurApName        (0x911)
  10. #define VALID(name)        ((name) && (((long)(name))&0xFFFF) && ((((long)(name))>>16)&0xFFFF))
  11. #define pstrcpy(s1,s2)    do { *(s1) = 0; pstrcat(s1,s2); } while(false)
  12.  
  13. // prototypes
  14. inline void pstrcat( StringPtr s1, StringPtr s2 );
  15. Boolean my_strncmp( void* s1, void* s2, short n );
  16.  
  17. // globals
  18. extern Str63 volumeName;
  19. extern short volumeVRef;    
  20.  
  21.  
  22.  
  23.  
  24. void PatchFSDispatch( void )
  25. {
  26.     short    trap = _FSDispatch;
  27.     Ptr        data;
  28.     Ptr        patch = (Ptr)MyFSDispatch;
  29.         
  30.     // fill in the necessary fields in 
  31.     data = (Ptr)NGetTrapAddress( trap, (trap & 0x0800) ? ToolTrap : OSTrap);
  32.     BlockMove( &data, patch+2, sizeof(data) );
  33.     
  34.     data = (Ptr)FSDispatchHelper;
  35.     BlockMove( &data, patch+6, sizeof(data) );
  36.     
  37.     // patch it
  38.     NSetTrapAddress( (UniversalProcPtr)MyFSDispatch, trap, (trap & 0x0800) ? ToolTrap : OSTrap);
  39. }
  40.  
  41.  
  42.  
  43. inline void pstrcat( StringPtr s1, StringPtr s2 )
  44. {
  45.     BlockMoveData( s2+1, s1+s1[0]+1, s2[0] );
  46.     s1[0] += s2[0];
  47. }
  48.  
  49. Boolean my_strncmp( void* s1, void* s2, short n )
  50. {
  51.     register Ptr p1 = (Ptr)s1, p2 = (Ptr)s2;
  52.     
  53.     while (n--)
  54.         if (*(p2++) != *(p1++)) return false;
  55.  
  56.     return true;
  57. }
  58.  
  59.  
  60.  
  61. asm void MyFSDispatch( void )
  62. {
  63.     bra.s    Begin
  64.         
  65. Real_FSDispatch:
  66.     dc.l    0                        // Saved address of the real FSDispatch code
  67.  
  68. FSDispatchHelper:
  69.     dc.l    0                        // our helper routine, which messes with the
  70.                                     //   parameter (FileParam*) we pass it...
  71. Begin:
  72.  
  73.     movem.l    d0-d2/a0-a2, -(a7)        // save volatile registers
  74.     
  75.     // okay, now we have a selector in D0, and a
  76.     // pointer to a fileParam in A0, because that's
  77.     // the way FSDispatch works.
  78.  
  79.     // let's jump off to our wonderful friend the helper function,
  80.     // to look at all the crap that got passed and see if we should
  81.     // modify what it says.
  82.     
  83.     move.l    a0, -(a7)                // push the FileParam onto the stack
  84.     move.l    FSDispatchHelper, a0    // load FSDispatchHelper
  85.     jsr        (a0)                    // call it
  86.     add.l    #4, a7                    // fix the stack
  87.     
  88.     // Clean up
  89.     movem.l    (a7)+, d0-d2/a0-a2
  90.     
  91.     // Pass control to the real FSDispatch
  92.     move.l    Real_FSDispatch, a1
  93.     jmp        (a1)
  94. }
  95.  
  96.  
  97.  
  98. void FSDispatchHelper( FileParam *pb )
  99. {
  100.     static Str255 patchedName;
  101.  
  102.     EnterCodeResource();
  103.     
  104.     // make sure pb is valid
  105.     if (!pb) goto done;
  106.  
  107.     // make sure we're only messing with the Microsoft installer
  108.     if ( !(*(long*)CurApName == 'Micr') ) goto done;
  109.  
  110.     // and make sure we've got a real ptr
  111.     if ( !VALID(pb->ioNamePtr) ) goto done;
  112.     
  113.     // first, if it's talking about the root directory
  114.     // notice we're not bothering to discuss the parameter; this
  115.     // is bad monkey but it's much easier this way...
  116.     
  117.     if ((pb->ioVRefNum == -1 || pb->ioVRefNum == 0) &&
  118.         pb->ioFlNum == 2 )
  119.     {
  120.         // see if it's talking about the Microsoft folder
  121.         if ( my_strncmp( pb->ioNamePtr+1, "Microsoft", 9 ) )
  122.         {
  123.             if ( (pb->ioNamePtr[0]==9) ||    // ref to the folder itself
  124.                 ((pb->ioNamePtr[0]>=10) && (pb->ioNamePtr[10]==':')) )    // or something inside
  125.             {
  126.                 pstrcpy( patchedName, "\p:System Folder:" );
  127.                 pstrcat( patchedName, pb->ioNamePtr );
  128.                 pstrcpy( pb->ioNamePtr, patchedName );
  129.                 
  130.                 goto done;
  131.             }
  132.         }
  133.     }
  134.     
  135.     // see if it's giving a full pathname
  136.     if ( my_strncmp( pb->ioNamePtr+1, volumeName+1, *volumeName ) &&
  137.          my_strncmp( pb->ioNamePtr+1+*volumeName, ":Microsoft", 10 ) )
  138.     {
  139.         // sure looks like it; check further though
  140.         if ( (pb->ioNamePtr[0]==*volumeName+10) ||    // ref to the folder itself
  141.             ((pb->ioNamePtr[0]>(*volumeName+10)) && (pb->ioNamePtr[*volumeName+12]==':')) ) // something inside
  142.         {
  143.             pstrcpy( patchedName, volumeName );
  144.             pstrcat( patchedName, "\p:System Folder:" );
  145.             
  146.             pb->ioNamePtr[*volumeName+11] = pb->ioNamePtr[0] - (*volumeName+1);
  147.             pstrcat( patchedName, pb->ioNamePtr );
  148.             pstrcpy( pb->ioNamePtr, patchedName );
  149.  
  150.             goto done;
  151.         }
  152.     }
  153.     
  154.  
  155.     // see if it's a partial path based off the root dir
  156.     if ( pb->ioFlNum == 0 && (pb->ioVRefNum==0 || pb->ioVRefNum==-1) )
  157.     {
  158.         // ok, are we talking about the Microsoft folder?
  159.         if ( my_strncmp(pb->ioNamePtr + 1,":Microsoft",10) )
  160.         {
  161.             if ( (pb->ioNamePtr[0]==10) ||    // ref to the folder itself
  162.                 ((pb->ioNamePtr[0]>=11) && (pb->ioNamePtr[11]==':')) )    // something inside
  163.             {
  164.                 pstrcpy( patchedName, "\p:System Folder" );
  165.                 pstrcat( patchedName, pb->ioNamePtr );
  166.                 pstrcpy( pb->ioNamePtr, patchedName );
  167.                 
  168.                 
  169.                 goto done;
  170.             }
  171.         }
  172.     }
  173.     
  174.     // else it looks like we don't do anything.
  175. done:
  176.     ExitCodeResource();
  177.     return;
  178. }
  179.  
  180.  
  181.  
  182.  
  183.  
  184.  
  185.  
  186.